<?php

trait Trait_Api_Car
{
    /**
     * 获取筛选的报价
     * @return array
     */
    private static function get_prices()
    {
        $data = DB::select('id', 'min', 'max')
            ->from('car_pricelist')
            ->where(DB::expr('webid is null'))
            ->execute()
            ->as_array();
        foreach ($data as &$row) {
            if ($row['min'] && $row['max']) {
                $row['name'] = $row['min'].'-'.$row['max'];
            } else {
                if ( ! $row['min']) {
                    $row['name'] = $row['max'].'以下';
                } else {
                    if ( ! $row['max']) {
                        $row['name'] = $row['min'].'以上';
                    }
                }
            }
            unset($row['min'], $row['max']);
        }
        return $data;
    }

    /**
     * 获取推荐列表
     * @return array
     */
    public function recommend($mid, $pagesize = 5)
    {
        $field = 'id,sellpoint,kindlist,title,litpic,shownum,price,price_date,satisfyscore,bookcount,attrid,iconlist,carkindid,use_type,sellpoint';
        $builder = DB::select(DB::expr($field))
            ->from('car')
            ->where('ishidden', '=', 0)
            ->where('price', '>', 0)
            ->where('status', '=', 3)
            ->order_by(DB::expr('ifnull(displayorder,9999)'), 'asc')
            ->offset(0)
            ->limit($pagesize);
        $list = $builder->execute()->as_array();
        $list = $this->format_car($list, $mid);
        return array(
            'list' => $list
        );
    }

    private function format_car($list, $mid)
    {
        if(empty($list)){
            return $list;
        }

        // 获取营销策略
        $marketing_strategy = Model_Api_V2_Marketing_Strategy::get_instance(self::TYPE_ID, array('mid'=> $mid));

        $out = [];
        $filter_keys = array(
            'id',
            'title',
            'litpic',
            'attrlist',
            'icon_list',
            'commentnum',
            'score',
            'kindname',
            'price',
            'sellnum',
            'car_kind_name',
            'satisfyscore',
            'carkindid',
            'use_type',
            'marketing_strategy',
            'sellpoint'
        );
        $uni_img = Model_Uniapp_Images::get_img_list(self::TYPE_ID);
        foreach ($list as &$v) {
            if(isset($uni_img[$v['id']])){
                $v['litpic'] = $uni_img[$v['id']];
            }
            $v['litpic'] = Model_Api_V2_System::uniapp_img($v['litpic'], 750, 750);
            $v['attrlist'] = Model_Car_attr::get_attr_list($v['attrid']);
            $v['icon_list'] = $this->icons($v['iconlist']);
            $v['commentnum'] = Model_Comment::get_comment_num($v['id'], self::TYPE_ID); //评论次数
            $v['score'] = St_Functions::get_satisfy(self::TYPE_ID, $v['id'], $v['satisfyscore']);
            $kind_name = '';
            if ( ! empty($v['kindlist'])) {
                $kind_name = DB::select('kindname')
                    ->from('destinations')
                    ->where('id', 'in', explode(',', $v['kindlist']))
                    ->execute()
                    ->as_array();
            }
            $satisfyscore = St_Functions::get_satisfy(self::TYPE_ID, $v['id'], $v['satisfyscore']);
            $v['kindname'] = $kind_name;
            $v['satisfyscore'] = str_replace('%','',$satisfyscore);
            $v['price'] = Model_Car::get_minprice($v['id'], $v);
            $v['sellnum'] = Model_Member_Order::get_sell_num($v['id'], self::TYPE_ID) + (int)$v['bookcount']; //销售数量
            $v['car_kind_name'] = Model_Car_Kind::get_carkindname($v['carkindid']);
            $v['marketing_strategy'] = $marketing_strategy->get_support_application($v['id']);
            $out[] = $this->filter_data($filter_keys, $v);
        }
        return $out;
    }

    /**
     * 获取租车车型
     * @return array
     * User: netman
     * Date: 2023/10/9 11:30
     */
    public function car_kind_list()
    {
        $list = DB::select('id', 'kindname', 'title')->from('car_kind')->execute()->as_array();
        foreach ($list as $k => $datum) {
            $count = DB::select()
                ->from('car')
                ->where('ishidden', '=', 0)
                ->and_where('carkindid', '=', $datum['id'])
                ->execute()
                ->count();
            if ( ! $count) {
                unset($list[$k]);
            }
        }
        return array_values($list);
    }

    /**
     * 按属性获取车辆列表
     * @param $kind_id
     * @param $offset
     * @param $row
     * @param $mid
     * @return array
     */
    public function get_cars_by_kind($kind_id, $offset, $row, $mid)
    {
        $field = "id,sellpoint,kindlist,title,litpic,shownum,price,price_date,satisfyscore,gain_address,";
        $field .= "bookcount,attrid,iconlist,carkindid,use_type";
        $list = DB::select(DB::expr($field))
            ->from('car')
            ->where('ishidden', '=', 0)
            ->where('carkindid', '=', $kind_id)
            ->where('status', '=', 3)
            ->order_by(DB::expr('displayorder asc,modtime desc,addtime desc'))
            ->offset($offset)
            ->limit($row)
            ->execute()
            ->as_array();
        $list = $this->format_car($list, $mid);
        return $list;
    }

    /**
     * 获取日历报价
     * @param $params
     * @return array
     * User: netman
     * Date: 2023/10/9 16:07
     */
    public function get_everyday_price($params)
    {
        //套餐id
        $suit_id = $params['suit_id'];
        $seckill_id = $params['is_seckill'];
        $together_id = $params['together_id'];

        $now_day = strtotime(date('Y-m-d'));

        //开始时间
        $starttime = empty($params['starttime']) ? $now_day : strtotime($params['starttime']);
        $starttime = max($starttime, $now_day);

        //结束时间
        $endtime = empty($params['endtime']) ? $now_day : strtotime($params['endtime']);
        $endtime = max($endtime, $starttime);


        if ($seckill_id) {
            $data = Model_Seckill::get_car_everyday_price($suit_id, $seckill_id);
        } else {
            if ($together_id) {
                $params = array(
                    'start_time' => $starttime,
                    'end_time' => $endtime,
                    'member_id' => $this->mid
                );
                $data = Model_Api_V2_Together::get_price_calendar($together_id, $params);
            } else {
                $data = DB::select('adultprice', 'day', 'number')
                    ->from('car_suit_price')
                    ->where('suitid', '=', $suit_id)
                    ->and_where('supplier_channel_id', '=', 1)
                    ->and_where('day', '>=', $starttime)
                    ->and_where('day', '<=', $endtime)
                    ->and_where('adultprice', '>', 0)
//                    ->and_where('number', '!=', 0)
                    ->group_by('day', 'suitid')
                    ->order_by('day', 'asc')
                    ->execute()
                    ->as_array();
            }
        }

        foreach ($data as & $datum) {
            $datum['price'] = Currency_Tool::price($datum['adultprice']);
            $datum['fulldate'] = date('Y-m-d', $datum['day']);
            unset($datum['adultprice']);
        }
        return $data;
    }

    /**
     * 套餐详情
     * @param $params
     * @return mixed|null
     * @throws Exception
     * User: netman
     * Date: 2023/10/9 16:11
     */
    public function car_suit($params)
    {
        $suit_id = $params['suit_id'];
        $car_id = $params['car_id'];
        $seckill_id = $params['is_seckill']; //秒杀id
        $together_id = $params['together_id']; //拼团id

        $car = DB::select('title')->from('car')->where('id', '=', $car_id)->execute()->current();
        if ( ! $car) {
            throw new Exception('车辆不存在');
        }
        $car_suit = DB::select()
            ->from('car_suit')
            ->where('id', '=', $suit_id)
            ->and_where('carid', '=', $car_id)
            ->execute()
            ->current();
        if ( ! $car_suit) {
            throw new Exception('套餐不存在');
        }

        /*存在就修改为秒杀价*/
        if ($seckill_id) {
            $seckill = Model_Seckill::get_seckill($seckill_id);
            if ( ! $seckill) {
                throw new Exception('秒杀不存在');
            }
            $car_suit['paytype'] = 1;
            $car_suit['number'] = $seckill['purchase_limits'] > 0 && $seckill['purchase_limits'] < $seckill['number'] ? $seckill['purchase_limits'] : $seckill['number'];//库存;
            $car_suit['content'] = $seckill['describe'];
        } else {
            if ($together_id) {
                $params = array('product_id' => $car_id, 'suit_id' => $suit_id);
                $together = Model_Api_V2_Together::check_book_product($together_id, $params);
                $limit_stock = Model_Together::limit_stock($together);
                $car_suit['paytype'] = 1;
                $car_suit['number'] = $limit_stock;
            }
        }

        $car_suit['productname'] = $car['title'];
        $car_suit['title'] = $car_suit['suitname'];

        // 退款规则
        $refund_class            = Service_Refund_Rule_Factory::get_instance(self::TYPE_ID);
        $car_suit['refund_rule'] = $refund_class->get_format_refund_rule($suit_id);
        unset($car_suit['lastoffer'], $car_suit['suitname'], $car_suit['price']);
        return $car_suit;
    }

    /**
     * 租车套餐信息
     * @param $product_id
     * @param $params
     * @return array
     * User: netman
     * Date: 2023/10/9 15:32
     */
    private function suit($product_id, $params = array(),$use_type=0)
    {
        $pay_name = array(
            '1' => '全款支付',
            '2' => '定金支付',
            '3' => '二次确认',
        );

        $get_time_desc  = $this->get_time_desc($use_type,json_decode($params['time_desc'],true));

        $where = "  where `carid`={$product_id}";
        $where .= " AND `day`>={$get_time_desc['start_time']}";
        $where .= " AND `day`<={$get_time_desc['end_time']}";
        $where .= " AND `adultprice`>0";
        $where .= " AND (`number`>0 or number=-1)";
        $having = " having COUNT(carid)>={$get_time_desc['days']}";
        //查询符合连续天数预订的房型
        $sql = "SELECT suitid,carid FROM sline_car_suit_price {$where} GROUP BY suitid {$having}";
        $data = DB::query(Database::SELECT, $sql)->execute()->as_array();
        $suit_ids  =array_column($data,'suitid');
        if(empty($suit_ids)){
            return [];
        }
        $suitTypes = DB::select('id', 'kindname')
            ->from('car_suit_type')
            ->where('carid', '=',
                $product_id)
            ->execute()
            ->as_array();
        $suitTypeArr = array();
        foreach ($suitTypes as $suitType) {
            $suitTypeArr[$suitType['id']] = $suitType['kindname'];
        }

        $query = DB::select('id', 'carid', 'suitname', 'content', 'price', 'jifenbook', 'jifentprice', 'jifencomment',
            'paytype', 'dingjin', 'number', 'refund_restriction', 'suittypeid', 'refund_restriction','sellprice')
            ->from('car_suit')
            ->where('carid', '=', $product_id)
            ->where('id', 'in', $suit_ids);
        if ($params['card_suit_id']) {
            $query->where('id', 'IN', explode(',', $params['card_suit_id']));
        }
        $suit = $query->order_by('displayorder', 'ASC')
            ->execute()
            ->as_array();

        $data = array();
        if(!empty($suit)) {
            $refund_class = Service_Refund_Rule_Factory::get_instance(self::TYPE_ID);
            foreach ($suit as $r) {
                $beforBook = array(
                    'suitid' => $r['id'],
                    'info' => $r,
                );
                $r['price'] = Model_Car::get_minprice($r['carid'], $beforBook);
                $r['title'] = $r['suitname'];
                $r['paytype_name'] = $pay_name[$r['paytype']];
                $r['content'] = (new Model_Api_V2_Xcx())->filter_content($r['content']);
                $r['refund_rule']  = $refund_class->get_format_refund_rule($r['id']);

                if (isset($suitTypeArr[$r['suittypeid']])) {
                    if (isset($data[$r['suittypeid']])) {
                        $data[$r['suittypeid']]['list'][] = $r;
                    } else {
                        $data[$r['suittypeid']]['type_name'] = $suitTypeArr[$r['suittypeid']];
                        $data[$r['suittypeid']]['list'][] = $r;
                    }
                }
            }
        }

        return array_values($data);
    }

    /**
     * @desc 获取线路详细行程内容
     * @param $params
     * @return array
     */
    private function get_detail_content($params)
    {
        $default = array(
            'typeid' => self::TYPE_ID,
            'productinfo' => 0,
            'onlyrealfield' => 1,
            'pc' => 0,

        );
        $params = array_merge($default, $params);
        extract($params, true);
        $arr = DB::select()->from('car_content')
            ->where('webid', '=', 0)
            ->and_where('isopen', '=', 1)
            ->order_by('displayorder', 'ASC')
            ->execute()
            ->as_array();

        //扩展表数据
        $productid = $productinfo['id'];//产品id
        $ar = DB::select()->from('car_extend_field')->where('productid', '=', $productid)->execute()->as_array();

        $list = array();
        foreach ($arr as $v) {
            if ($v['columnname'] == 'tupian') {
                continue;
            }
            if ($v['isrealfield'] == 1) {
                $content = ! empty($productinfo[$v['columnname']]) ? $productinfo[$v['columnname']] : $ar[0][$v['columnname']];
                $content = $content ? $content : '';
            }
            if (empty($content)) {
                continue;
            }

            $a = array();
            $a['columnname'] = $v['columnname'];
            $a['chinesename'] = $v['chinesename'];
            $a['content'] = $this->content_add_domain($content);
            $list[] = $a;
        }

        return $list;
    }

    /**
     * @desc 属性生成where条件,用于多条件属性搜索
     * @param $attrid
     * @return string
     */
    private function get_attr_where($attrid)
    {
        $arr = Common::remove_arr_empty(explode('_', $attrid));
        foreach ($arr as $value) {
            $value = (int)$value;
            if ($value != 0) {
                $str .= " and FIND_IN_SET($value,sline_car.attrid) ";
            }
        }

        return $str;
    }

    /**
     * 获取筛选的属性列表
     * @return array
     */
    private function get_attributes()
    {
        $data = $this->get_attributes_by_pid();
        foreach ($data as &$row) {
            $row['child'] = $this->get_attributes_by_pid($row['id']);
        }
        return $data;
    }

    /**
     * 通过父级id获取属性
     * @param $pid
     * @return array
     */
    private function get_attributes_by_pid($pid = 0)
    {
        return DB::select('id', array('attrname', 'name'))
            ->from('car_attr')
            ->where('pid', '=', $pid)
            ->and_where('isopen', '=', 1)
            ->order_by(DB::expr('ifnull(displayorder,9999)'), 'asc')
            ->execute()
            ->as_array();
    }


    /**
     * 创建订单信息
     * @param $request_param
     * @param $car
     * @param $suit
     * @param $extend_data
     * @param $user_info
     * @return array
     */
    private function make_order($request_param, $car, $suit, $extend_data, $user_info)
    {
        $ding_num = Arr::get($request_param, 'ding_num');
        $linktel = Arr::get($request_param, 'linktel');
        $linkman = Arr::get($request_param, 'linkman');
        $link_email = Arr::get($request_param, 'linkemail', '');
        $remark = Arr::get($request_param, 'remark', '');

        // 订单来源 1PC,2WAP,3小程序,4平台添加
        $source = Arr::get($request_param, 'source', 3);
        // 支付方式： 1-全款 2-定金 3-线下
        $paytype = Arr::get($request_param, 'paytype', 1);
//        $use_date = Arr::get($request_param, 'usedate');
//        $departdate = Arr::get($request_param, 'departdate');
        $time_desc = Arr::get($request_param, 'time_desc', '');
        $time_desc = json_decode($time_desc,true);
        $get_time_desc = $this->get_time_desc($car['use_type'],$time_desc);

        $use_date=date('Y-m-d',$get_time_desc['start_time']);
        $departdate=date('Y-m-d',$get_time_desc['end_time']);

        $need_jifen = Arr::get($request_param, 'needjifen', 0);

        $need_confirm = $suit['paytype'] == 3 ? 1 : 0;

        // 计算预订金额
        $dingjin = $suit['dingjin'];
        $total_day =$get_time_desc['days'] ;
        $order_dingjin = $dingjin * ($total_day + 1);

        // 租车范围内单价
        if (isset($extend_data['together_info'])) {
            // 拼团
            $together_price = $extend_data['together_info']['price'];
            // 重新计算价格
            $price = St_Math::mul(array($together_price['adult_price'], $total_day), 2);
            $price = Currency_Tool::price($price);
        } else {
            $price = Model_Car::suit_range_price($suit['id'], $use_date, $departdate, 1);
        }

        if($car['use_type']==0){
            $time_desc_string=['start_date'=>$use_date,'end_date'=>$departdate];
        }else{
            $time_desc_string=['start_date'=>$time_desc['start_time'],'end_date'=>$time_desc['end_time']];
        }
        $order = array(
            'webid' => 0,
            'addtime' => time(),
            'dingnum' => $ding_num,
            'linktel' => $linktel,
            'linkman' => $linkman,
            'linkemail' => $link_email,
            'typeid' => self::TYPE_ID,
            'ordersn' => St_Product::get_ordersn('03'),
            'source' => $source,
            'productautoid' => $car['id'],
            'productaid' => $car['aid'],
            'litpic' => $car['litpic'],
            'productname' => $car['title'],
            'remark' => $remark,
            'suitid' => $suit['id'],
            'dingjin' => $order_dingjin,
            'suit_name' => $suit['suitname'],
            'refund_restriction' => $suit['refund_restriction'],
            'paytype' => $paytype,
            'usedate' => $use_date,
            'departdate' => $departdate,
            'time_desc' => json_encode($time_desc_string),
            'need_confirm' => $need_confirm,
            'status' => $need_confirm == 1 ? 0 : 1,
            'price' => doubleval($price),
            'self_pickup'=>$request_param['self_pickup']?json_encode($request_param['self_pickup']):''
        );

        // 自动关闭订单时间
        $auto_close_time = $suit['auto_close_time'] ?: 0;
        if ($auto_close_time) {
            $order['auto_close_time'] = $auto_close_time + time();
        }
        // 待确认时限
        $auto_confirm_time = $suit['auto_confirm_time'] ?: 0;
        if ($auto_confirm_time) {
            $order['auto_confirm_time'] = $auto_confirm_time + time();
        }

        //自动退款时限
        $use_date=trim($request_param['use_date']);
        $no_confirm_refund = $suit['no_confirm_refund'] ?: 0;
        if ($no_confirm_refund) {
            $order['no_confirm_refund'] = strtotime($use_date . ' +1 day') -  $no_confirm_refund ;
        }

        /**--------------- 积分信息------------- */
        $jifenbook = $car['jifenbook_id'];
        $order['jifenbook'] = $jifenbook;
        //积分抵现
        if ($need_jifen) {
            $jifentprice = Model_Jifen_Price::calculate_jifentprice($car['jifentprice_id'], self::TYPE_ID, $need_jifen,
                $user_info);
            $use_jifen = empty($jifentprice) ? 0 : 1;
            $need_jifen = empty($jifentprice) ? 0 : $need_jifen;
            $order['usejifen'] = $use_jifen;
            $order['needjifen'] = $need_jifen;
            $order['jifentprice'] = $jifentprice;
        }

        //积分评论
        $jifencomment_info = Model_Jifen::get_used_jifencomment(self::TYPE_ID);
        $jifencomment = empty($jifencomment_info) ? 0 : $jifencomment_info['value'];
        $order['jifencomment'] = $jifencomment;
        /**-------------------------------- 积分信息--------------------- */

        return $order;
    }

    /**
     * 获取预订的总天数
     * @param $use_date
     * @param $depart_date
     * @return int
     * @throws Exception
     */
    private function get_order_total_day($use_date, $depart_date)
    {
        $date1 = new DateTime($use_date);
        $date2 = new DateTime($depart_date);
        $interval = date_diff($date1, $date2);
        $days = $interval->format('%a');
        return (int)$days + 1;
    }

    /**
     * 验证订单请求参数
     * @param $request_param
     * @return array
     * @throws Exception
     */
    private function check_order_params($request_param)
    {
        $member_id = Arr::get($request_param, 'mid');
        $product_id = Arr::get($request_param, 'product_auto_id');
        $ding_num = Arr::get($request_param, 'ding_num');
//        $use_date = Arr::get($request_param, 'usedate');
//        $depart_date = Arr::get($request_param, 'departdate');
        $time_desc = Arr::get($request_param, 'time_desc');


        $car = DB::select()
            ->from('car')
            ->where('id', '=', $product_id)
            ->execute()
            ->current();
        if ( ! $car) {
            throw new Exception("车辆不存在");
        }

        //套餐信息
        $suit_id = $request_param['suit_id'];
        $suit_info = Model_Car_Suit::suit_info($suit_id);
        if (empty($suit_info) || ! $suit_info['id']) {
            throw new Exception("套餐不存在");
        }

        //查询符合连续天数预订的房型
        $use_type = $car['use_type'];
        $time_desc = json_decode($time_desc,true);
        $get_time_desc  = $this->get_time_desc($use_type,$time_desc);

        $use_date = $get_time_desc['start_time'];
        $depart_date = $get_time_desc['end_time'];

        $where = "  where `suitid`={$suit_id}";
        $where .= " AND `day`>={$use_date}";
        $where .= " AND `day`<={$depart_date}";
        $where .= " AND `adultprice`>0";
        $having = " having COUNT(carid)>={$get_time_desc['days']}";
        $sql = "SELECT suitid,carid FROM sline_car_suit_price {$where} GROUP BY suitid {$having}";
        $day_data = DB::query(Database::SELECT, $sql)->execute()->as_array();
        if (!$day_data) {
            throw new Exception("还车日期有误");
        }

        // 检查库存-新版包车租车验证库存
        $storage_status = Model_Car::check_storage($product_id, $ding_num, $suit_id, date('Y-m-d',$use_date), date('Y-m-d',$depart_date));
        if ( ! $storage_status) {
            throw new Exception("部分日期库存不足");
        }

        // 检查拼团或凑团限制
        $together_id = Arr::get($request_param, 'together_id', 0);
        $join_id = Arr::get($request_param, 'join_id', 0);
        if ($together_id > 0 || $join_id > 0) {
            $together_params = array('join_id' => $join_id, 'ding_num' => $ding_num);
            $check_order_together = Model_Api_V2_Together::check_order_together($together_id, $member_id,
                $together_params);
            if ( ! $check_order_together['status']) {
                throw new Exception($check_order_together['msg']);
            }
            $together_info = $check_order_together['data'];
        }

        $extend_data = array();
        if (isset($together_info)) {
            $extend_data['together_info'] = $together_info;
        }

        return array($car, $suit_info, $extend_data);
    }

    /**
     * 处理订单秒杀数据
     * @param $seckill_id
     * @param $order
     * @return array
     * @throws Exception
     */
    private function make_order_seckill($seckill_id, $order)
    {
        $seckill = DB::select()->from('seckill')
            ->where('id', '=', $seckill_id)
            ->execute()
            ->current();
        if ($seckill) {
            // 保留原价
            $seckill['suit_original_adult_price'] = $order['price'];
        }
        return array($order, $seckill);
    }


}